package com.zk.config.web.op;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import com.github.zkclient.ZkClient;
import com.github.zkclient.ZkConnection;
import com.zk.config.web.model.TreeData;
import com.zk.config.web.util.ZkCacheUtil;

public class MyZkClient extends ZkClient {
	
	private Logger log = LoggerFactory.getLogger(MyZkClient.class);
	
	public ConcurrentMap<String, TreeData> zkData = new ConcurrentHashMap<>();
	
	public boolean useCache = false;
	
	@Value("${zookeeper.saveNodeDataToCache}")
	public boolean saveNodeDataToCache = false;
	
	public MyZkClient(String connectString) {
		super(connectString);
	}
	
	public MyZkClient(String connectString, int connectionTimeout) {
		super(connectString, 30000, connectionTimeout);
	}

	public MyZkClient(String connectString, int sessionTimeout, int connectionTimeout) {
		super(new ZkConnection(connectString, sessionTimeout), connectionTimeout);
	}
	
	@Override
	public void process(WatchedEvent event) {
		if(useCache) {
		    String path = event.getPath();
		    if (event.getType() != EventType.None && path != null) {
		        try {
		            if(event.getType() == EventType.NodeDeleted) {
		                // 清缓存
		                ZkCacheUtil.deleteNodeClearCache(this, path);
		            } else if (event.getType() == EventType.NodeCreated) {
		                // 回调继续监听监听变更的路径节点
		                if(getZooKeeper().exists(path, true) != null) {
		                    // 清缓存
		                    ZkCacheUtil.createNodeSetCache(this, path);
		                }
		            } else if(event.getType() == EventType.NodeDataChanged) {
		                getZooKeeper().exists(path, true); // 回调继续监听监听变更的路径节点
		                // 清缓存
		                ZkCacheUtil.changeNodeSetCache(this, path);
		            } else if(event.getType() == EventType.NodeChildrenChanged) {
		                // 继续监听监听变更的路径节点
		                ZkCacheUtil.flushChildrenSetCache(this, path, true);
		            }
		        } catch (Exception e) {
		            e.printStackTrace();
		            log.error(e.getMessage());
		        }
		    }
		    if (event.getState() == KeeperState.Expired) {
		        zkData.clear();
		    }
		}
		super.process(event);
	}
}
